﻿using System;
using System.Threading.Tasks;
using Pay.Core;
using Pay.DTO.rpayBh;
using Flurl.Http;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;

namespace Pay.Service {
	public class RpayBhSign {
		public RpayBhSign() {
		}
#if DEBUG
		protected string api_url = "http://47.96.9.32";
		public const string key = "7e985fd0ae284126812552a81ca1ccd3";
		public const string partner = "10000889";
#else
		protected string api_url = "http://116.62.246.200";
		public const string key = "fd7a2b6712e144788a34346dcd8ed978";
		public const string partner = "63519013";
#endif

		/// <summary>
		/// 请求
		/// </summary>
		/// <returns>The gateway.</returns>
		/// <param name="model">Model.</param>
		/// <typeparam name="T">The 1st type parameter.</typeparam>
		public async Task<T> PayGateway<T>(rpayBh_req_base model, string url) where T : rpayBh_resp_base, new() {
			var log = IocHelper.Get<ILogHelper>("info");
			model.partner = partner;
			model.sign = SecureHelper.MD5(_sign(model));
			var json = model.ToJson();
			log.Info(json);
			try {
				var resp1 = await (api_url + url).PostJsonAsync(model).ReceiveString();
				log.Info(resp1);
				return resp1.ToObject<T>();
				//var resp = await api_url.PostJsonAsync(model).ReceiveJson<T>();
				//log.Info(resp.ToJson());
				//return resp;
			} catch (FlurlHttpException ex) {
				log.Error(ex.Message);
				return null;
			}
		}

		/// <summary>
		/// 签名
		/// </summary>
		/// <returns>The sign.</returns>
		/// <param name="model">Model.</param>
		private string _sign(rpayBh_req_base model) {
			string json = model.ToJson();
			var collection = json.ToObject<SortedDictionary<string, object>>();
			collection.Remove("sign");
			string result = string.Empty;
			foreach (var kv in collection) {
				if (kv.Value is JObject) {
					var obj = kv.Value as JObject;
					result += "&" + kv.Key + "=" + obj.ToJson();
				} else {
					if (kv.Value != null && !string.IsNullOrEmpty(kv.Value.ToString()))
						result += "&" + kv.Key + "=" + kv.Value;
				}
			}
			result = result.Trim('&');
			result += "&key=" + key;
			var log = IocHelper.Get<ILogHelper>("info");
			log.Info(result);
			return result;
		}

		/// <summary>
		/// 异步通知验签
		/// </summary>
		/// <param name="model">Model.</param>
		public bool VerifySign(rpayBh_notify model) {
			var log = IocHelper.Get<ILogHelper>("info");
			var json = model.ToJson();
			log.Info(json);
			var collection = json.ToObject<SortedDictionary<string, object>>();
			var sign = collection["sign"].ToString();
			collection.Remove("sign");
			string result = string.Empty;
			foreach (var kv in collection) {
				if (kv.Value is JObject) {
					var obj = kv.Value as JObject;
					result += "&" + kv.Key + "=" + obj.ToJson();
				} else {
					if (kv.Value != null && !string.IsNullOrEmpty(kv.Value.ToString()))
						result += "&" + kv.Key + "=" + kv.Value;
				}
			}
			result = result.Trim('&');
			result += "&key=" + key;
			log.Info(result);
			result = SecureHelper.MD5(result);
			log.Info(result);
			return result == sign;
		}
	}
}
